package cloud.shyidong.tenant.service.impl;

import cloud.shyidong.cache.service.CacheService;
import cloud.shyidong.core.Result;
import cloud.shyidong.core.constant.TokenConstant;
import cloud.shyidong.core.context.ContextHolder;
import cloud.shyidong.core.context.TenantContextHolder;
import cloud.shyidong.core.exception.BusinessException;
import cloud.shyidong.core.util.DateUtils;
import cloud.shyidong.core.util.MD5Utils;
import cloud.shyidong.core.util.ObjectUtils;
import cloud.shyidong.core.util.StringUtils;
import cloud.shyidong.system.entity.SystemCacheEntity;
import cloud.shyidong.tenant.constant.TenantStatusConstant;
import cloud.shyidong.tenant.dao.*;
import cloud.shyidong.tenant.entity.TenantTenantEntity;
import cloud.shyidong.tenant.entity.TenantUserEntity;
import cloud.shyidong.tenant.request.TenantInfoUpdatePasswordRequest;
import cloud.shyidong.tenant.request.TenantInfoUpdateRequest;
import cloud.shyidong.tenant.service.SelfService;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Description TODO
 * @Author syd
 * @Date 2023/8/25
 */
@Service
public class SelfServiceImpl implements SelfService {
    
    private TenantMenuDao tenantMenuDao;
    
    private TenantFunctionDao tenantFunctionDao;
    
    private TenantUserDao tenantUserDao;
    
    private TenantTenantDao tenantTenantDao;
    
    private TenantTenantMenuDao tenantTenantMenuDao;
    
    private TenantTenantFunctionDao tenantTenantFunctionDao;
    
    private CacheService cacheService;
    
    @Autowired
    public void setTenantMenuDao(TenantMenuDao tenantMenuDao) {
        this.tenantMenuDao = tenantMenuDao;
    }
    
    @Autowired
    public void setTenantFunctionDao(TenantFunctionDao tenantFunctionDao) {
        this.tenantFunctionDao = tenantFunctionDao;
    }
    
    @Autowired
    public void setTenantUserDao(TenantUserDao tenantUserDao) {
        this.tenantUserDao = tenantUserDao;
    }
    
    @Autowired
    public void setTenantTenantDao(TenantTenantDao tenantTenantDao) {
        this.tenantTenantDao = tenantTenantDao;
    }
    
    @Autowired
    public void setTenantTenantMenuDao(TenantTenantMenuDao tenantTenantMenuDao) {
        this.tenantTenantMenuDao = tenantTenantMenuDao;
    }
    
    @Autowired
    public void setTenantTenantFunctionDao(TenantTenantFunctionDao tenantTenantFunctionDao) {
        this.tenantTenantFunctionDao = tenantTenantFunctionDao;
    }
    
    @Autowired
    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }
    
    @Override
    public Result getAuthInfo() {
        
        if (StringUtils.isEmpty(ContextHolder.getToken())) {
            return Result.ofErrors(BusinessException.noLogin());
        }
        
        SystemCacheEntity systemCacheEntity = cacheService.get(String.format(TokenConstant.TOKEN_TENANT_KEY, ContextHolder.getToken()));
        
        if (ObjectUtils.isNull(systemCacheEntity)) {
            return Result.ofErrors(BusinessException.noLogin());
        }
        
        return Result.ofData(systemCacheEntity.getValue());
    }
    
    @Override
    public Result getTreeList() {
        SystemCacheEntity systemCacheEntity = cacheService.get(String.format(TokenConstant.TOKEN_MENU_TREE_KEY, ContextHolder.getToken()));
        if (ObjectUtils.isNull(systemCacheEntity)) {
            return Result.ofData(null);
        }
        return Result.ofData(systemCacheEntity.getValue());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result update(TenantInfoUpdateRequest tenantInfoUpdateRequest) {
        
        //查询登录用户信息
        TenantUserEntity tenantUserEntity = tenantUserDao.selectById(ContextHolder.getContext().getUserId());
        
        //修改登录用户信息
        if (StringUtils.isNotEmpty(tenantInfoUpdateRequest.getName())) {
            tenantUserEntity.setName(tenantInfoUpdateRequest.getName());
        }
        if (StringUtils.isNotEmpty(tenantInfoUpdateRequest.getPhone())) {
            tenantUserEntity.setPhone(tenantInfoUpdateRequest.getPhone());
        }
        if (StringUtils.isNotEmpty(tenantInfoUpdateRequest.getEmail())) {
            tenantUserEntity.setEmail(tenantInfoUpdateRequest.getEmail());
        }
        if (StringUtils.isNotEmpty(tenantInfoUpdateRequest.getRemark())) {
            tenantUserEntity.setRemark(tenantInfoUpdateRequest.getRemark());
        }
        tenantUserEntity.setUpdateUser(ContextHolder.getContext().getUserId());
        tenantUserEntity.setUpdateTime(DateUtils.getNow());
        tenantUserDao.updateById(tenantUserEntity);
        
        tenantUserEntity.setPassword(null);
        cacheService.save(String.format(TokenConstant.TOKEN_TENANT_KEY, ContextHolder.getToken()), JSON.toJSONString(tenantUserEntity));
        
        return Result.ofData(null);
        
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updatePassword(TenantInfoUpdatePasswordRequest tenantInfoUpdatePasswordRequest) {
        
        //修改登录用户信息
        TenantUserEntity tenantUserEntity = tenantUserDao.selectById(ContextHolder.getContext().getUserId());
        
        //验证旧密码是否正确
        if (!tenantUserEntity.getPassword().equals(MD5Utils.md5Hex(tenantInfoUpdatePasswordRequest.getOldPassword()))) {
            throw BusinessException.from("旧密码输入错误");
        }
        
        //修改密码
        tenantUserEntity.setPassword(MD5Utils.md5Hex(tenantInfoUpdatePasswordRequest.getNewPassword()));
        tenantUserEntity.setUpdateUser(ContextHolder.getContext().getUserId());
        tenantUserEntity.setUpdateTime(DateUtils.getNow());
        tenantUserDao.updateById(tenantUserEntity);
        
        return Result.ofData(null);
    }
    
    @Override
    public Result logout() {
        
        if (StringUtils.isNotEmpty(ContextHolder.getToken())) {
            cacheService.delete(String.format(TokenConstant.TOKEN_TENANT_KEY, ContextHolder.getToken()));
            cacheService.delete(String.format(TokenConstant.TOKEN_MENU_KEY, ContextHolder.getToken()));
            cacheService.delete(String.format(TokenConstant.TOKEN_FUNCTION_KEY, ContextHolder.getToken()));
            cacheService.delete(String.format(TokenConstant.TOKEN_MENU_TREE_KEY, ContextHolder.getToken()));
        }
        
        return Result.ofData(null);
    }
    
    @Override
    public Result getTenant() {
        Long tenantId = TenantContextHolder.getTenantContext().getTenantId();
        TenantTenantEntity tenantTenantEntity = tenantTenantDao.selectById(tenantId);
        boolean extension = false;
        Date renewEndTime = null;
        if (tenantTenantEntity.getStatus().intValue() == TenantStatusConstant.NOT_AUTH || tenantTenantEntity.getStatus().intValue() == TenantStatusConstant.EXPIRE) {
            extension = true;
            renewEndTime = DateUtils.getAfterYear();
        } else if (tenantTenantEntity.getStatus().intValue() == TenantStatusConstant.AUTH) {
            if (DateUtils.getAfterDays(30).getTime() > tenantTenantEntity.getEndTime().getTime()) {
                extension = true;
            }
            renewEndTime = DateUtils.getAfterYear(tenantTenantEntity.getEndTime());
        }
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("name", tenantTenantEntity.getName());
        result.put("price", tenantTenantEntity.getPrice());
        result.put("endTime", tenantTenantEntity.getEndTime());
        result.put("renewEndTime", renewEndTime);
        result.put("status", tenantTenantEntity.getStatus());
        result.put("extension", extension);
        return Result.ofData(result);
    }
    
}
